<?php
/**
 * User: Jerry
 * Date: 2017/9/18
 * Time: 14:35
 */

namespace SDXApi\Listeners;


use SDXApi\Model\GoodsModel;
use SDXApi\Model\GoodsstorageModel;
use SDXApi\Model\OrderinfoModel;
use SDXApi\Model\UsersModel;

/**
 * 监听限购功能类
 * Class BuyNumberListener
 * @author Jerry
 * @package SDXApi\Listeners
 */
class BuyNumberListener
{

    /**
     * @var array
     */
    protected $message = array();

    /**
     * @var OrderinfoModel
     */
    protected $orderModel;

    /**
     * @var GoodsModel
     */
    protected $goodsModel;

    /**
     * @var array
     */
    protected $goodsInfo = array();

    /**
     * @var UsersModel
     */
    protected $userModel;

    /**
     * @var GoodsstorageModel
     */
    protected $goodsStorageModel;

    /**
     * BuyNumberListener constructor.
     */
    public function __construct()
    {
        $this->orderModel = new OrderinfoModel();
        $this->goodsModel = new GoodsModel();
        $this->userModel = new UsersModel();
        $this->goodsStorageModel = new GoodsstorageModel();
    }

    /**
     * 获取商品详情
     * @author Jerry
     * @param int $goodsId
     * @return $this
     */
    public function getGoodsInfo($goodsId = 0)
    {
        $this->goodsInfo = $this->goodsModel->findBuyNumberInfo($goodsId);
        return $this;
    }

    /**
     * 循环多维数组返回限购信息
     * @author Jerry
     * @param array $goods
     * @param int $userId
     * @return bool|string
     */
    public function getForeachGoodsIdStatus($goods = array(), $userId = 0)
    {
        if (empty($goods)) {
            return false;
        }

        foreach ($goods as $key => $value) {

            $status = $this->getGoodsInfo($value['goods_id'])->getGoodsNumberStatus($value['goods_number'], $userId);

            if (! empty($status)) {
                return $status;
            }
        }

        return false;
    }

    /**
     * 获取限购
     * @author Jerry
     * @param array $goods
     * @param int $number
     * @param int $userId
     * @return bool|string
     */
    public function getGoodsNumberStatus($number = 0, $userId = 0, $goods = array())
    {
        if (empty($goods)) {
            $goods = $this->goodsInfo;
        }

        $status = '';

        $promotePrice = $this->checkPromoteRank($goods, $userId, $number);
        if ($promotePrice > 0) {
            $status = $this->checkPromoteNumber($goods, $userId, $number);
        }
        else{
            $status = $this->checkGoodsNumber($goods, $number, $userId)->getStatusMessage();
        }

        return $status;
    }

    /**
     * @author Jerry
     * @param array $goods
     * @param int $userId
     * @param int $number
     * @return bool
     */
    protected function checkPromoteNumber($goods = array(), $userId = 0, $number = 0)
    {

        $count = $this->findOrderPromoteByToDay($userId, $goods['goods_sn']);

        $orderPromoteNumber = $this->findOrderPromoteByNumberTime($userId, $goods);

        $status = $this->thenPromote($goods, $count, $number, $orderPromoteNumber, $userId)->getStatusMessage();

        return $status;
    }

    /**
     * 返回当天此会员促销价的单个商品订单总数
     * Created by Jerry
     * @param $user_id
     * @param $goods_sn
     * @return mixed
     */
    protected function findOrderPromoteByToDay($user_id, $goods_sn)
    {
        return $this->orderModel->get_order_promote_by_to_day_for_count($user_id, $goods_sn);
    }

    /**
     * 返回促销价期间内该用户此商品所有订单总数
     * Created by Jerry
     * @param $uid
     * @param $goodsInfo
     * @return mixed
     */
    protected function findOrderPromoteByNumberTime($uid, $goodsInfo)
    {
        return $this->orderModel->get_order_promote_by_number($uid, $goodsInfo['goods_sn'], $goodsInfo['promote_start_date'], $goodsInfo['promote_end_date']);
    }

    /**
     * 判断是否在促销价限制范围内
     * @author Jerry
     * @param $goodsInfo
     * @param $toDayNumber
     * @param $goodsNumber
     * @param $orderPromoteNumber
     * @param int $uid
     * @return $this
     */
    protected function thenPromote($goodsInfo, $toDayNumber, $goodsNumber, $orderPromoteNumber, $uid = 0)
    {

//		限购商品数量
        if ($goodsInfo['promote_goods_number'] > 0 && $goodsInfo['promote_goods_number'] < $goodsNumber) {
            $this->setStatusMessage('此促销商品已超出单次购买数量超过上限');
        }

//		每天限购数量
        if ($goodsInfo['promote_today_number'] > 0 && $goodsInfo['promote_today_number'] <= $toDayNumber) {
            $this->setStatusMessage('此促销商品已超出当天可购买数量');
        }

        if ($goodsInfo['promote_today_number'] < 0 && abs($goodsInfo['promote_today_number']) <= $orderPromoteNumber) {
            $this->setStatusMessage('此促销商品已超出此次促销活动可购买数量');
        }

//		判断会员等级促销价
        $promotePrice = $this->checkPromoteRank($goodsInfo, $uid, $goodsNumber);
        if ($promotePrice <= 0) {
            $this->setStatusMessage('您暂时无法享受此促销活动');
        }

//		促销库存
        $storageNumber = $this->getBuyNowGoodsNumber($goodsInfo) + 0;
        if (($goodsInfo['promote_number'] > 0) && (($goodsInfo['promote_number'] < ($goodsNumber + $storageNumber)))) {
            $this->setStatusMessage('促销商品已卖完');
        }

        return $this;
    }

    /**
     * @author Jerry
     * @param array $goodsInfo
     * @param int $userId
     * @param int $number
     * @return bool|float|int
     */
    protected function checkPromoteRank($goodsInfo = array(), $userId = 0, $number = 0)
    {
        if (empty($goodsInfo) || empty($userId)) {
            return false;
        }

        if ($goodsInfo['is_buynow'] != 0) {
            return 0;
        }

        $userRank = $this->userModel->get_user_rank($userId);

        $price = 0;

//		促销库存
        $storageNumber = $this->getBuyNowGoodsNumber($goodsInfo) + 0;
        if (($goodsInfo['promote_number'] > 0) && ($goodsInfo['promote_number'] < ($storageNumber + $number))) {
            return 0;
        }

//		指定用户
        if ($userRank['user_rank'] == $goodsInfo['promote_user_rank']) {
            $price = bargain_price($goodsInfo['promote_price'], $goodsInfo['promote_start_date'], $goodsInfo['promote_end_date']);
        }

//		全部用户
        if ($goodsInfo['promote_user_rank'] == 3 || $goodsInfo['promote_user_rank'] == 0) {
            $price = bargain_price($goodsInfo['promote_price'], $goodsInfo['promote_start_date'], $goodsInfo['promote_end_date']);
        }

//		特殊用户等级
        if ($goodsInfo['promote_user_rank'] == 1 && $userRank['user_rank'] == 0) {
            $price = bargain_price($goodsInfo['promote_price'], $goodsInfo['promote_start_date'], $goodsInfo['promote_end_date']);
        }

        return $price;

    }

    /**
     * @author Jerry
     * @param $goods
     * @return bool
     */
    protected function getBuyNowGoodsNumber($goods)
    {
        if (empty($goods)) {
            return false;
        }

        return $this->goodsStorageModel->findGoodsPromoteOrderNumber($goods['goods_id'], $goods['promote_start_date'], $goods['promote_end_date']);
    }

    /**
     * 校验限购
     * @author Jerry
     * @param array $goods
     * @param int $number
     * @param int $userId
     * @return $this
     */
    protected function checkGoodsNumber($goods = array(), $number = 0, $userId = 0)
    {
        if (empty($goods)) {
            $this->setStatusMessage('操作异常，不存在商品');
        }

        if (($goods['buy_number'] > 0) && ($goods['buy_number'] < $number)) {
            $this->setStatusMessage('【' . $goods['goods_name'] . '】商品，每次限购' . $goods['buy_number'] . '件');
        }

//        if (($goods['buy_number'] < 0) && (abs($goods['buy_number']) < abs($number))) {
//            $this->setStatusMessage('【' . $goods['goods_name'] . '】每人限购' . abs($goods['buy_number'] . '件'));
//            return $this;
//        }

        if ($goods['buy_today_number'] > 0) {
            $orderNumber = $this->getUserOrderGoodsNumberCount($userId, $goods['goods_id']) + 0;

            if ($goods['buy_today_number'] <= $orderNumber) {
                $this->setStatusMessage('【' . $goods['goods_name'] . '】商品，每人每天只能购买' . $goods['buy_today_number'] . '次');
            }
        }

        return $this;
    }

    /**
     * 设置限购信息
     * @author Jerry
     * @param string $message
     * @return $this
     */
    protected function setStatusMessage($message = '')
    {
        array_push($this->message, $message);
        return $this;
    }

    /**
     * 获取限购信息
     * @author Jerry
     * @return string
     */
    protected function getStatusMessage()
    {
        return implode(',', $this->message);
    }

    /**
     * 获取该会员当天订单商品数量
     * @author Jerry
     * @param int $userId
     * @param int $goodsId
     * @return mixed
     */
    protected function getUserOrderGoodsNumberCount($userId = 0, $goodsId = 0)
    {
        return $this->orderModel->findOrderGoodsSumByUserId($userId, $goodsId);
    }
}